/* 
 * File:   Loader.cpp
 * Author: shadius
 * 
 * Created on 11. listopad 2012, 8:44
 */

#include "Loader.h"
using namespace std;

Loader::Loader(string filename) :
		filename(filename) {
}

Loader::Loader(const Loader& orig) {
}

Loader::~Loader() {
}

bool Loader::load() {
	//    vector<string> row;
	//    string line;
	//    ifstream in(filename);
	//    if (in.fail()) {
	//        cout << "File not found" << endl;
	//        return;
	//    }

	vector<string> rows;
	if (!loadFileToVector(rows)) {
		cout << "File not found" << endl;
		return false;
	}
	parseLines(rows);
	return true;
}

DataSet Loader::transformToDataSet(vector<string> &rows, int BGIndex,
		int IGIndex) {
	vector<string> row;
	p_BGValues.reset();
	p_IGValues.reset();
	p_BGValues = make_shared<DataSet>(rows.size());
	p_IGValues = make_shared<DataSet>(rows.size());
	DataSet data(rows.size());
	for (unsigned i = 0; i < rows.size(); i++) {
		csvline_populate(row, rows[i], DELIMITIER);
		StringUtils::replace(row[BGIndex], ",", ".");
		StringUtils::replace(row[IGIndex], ",", ".");
		p_BGValues->add(i , convertToDouble(row[BGIndex]));
		//p_BGValues->add(COLUMN_TIME, i, sec);
		p_IGValues->add(i, convertToDouble(row[IGIndex]));
		//p_IGValues->add(COLUMN_TIME, i, sec);
	}
	return data;
}

DataSet Loader::parseLines(vector<string> &rows) {
	vector<string> row;
	string line = rows[0];
	csvline_populate(row, line, DELIMITIER);
	int BGIndex = -1;
	int IGIndex = -1;
	findColumnsIndex(row, BGIndex, IGIndex);

	cout << "BGIndex: " << BGIndex << endl;
	cout << "IGIndex: " << IGIndex << endl;
	//remove header

	rows.erase(rows.begin());

	boost::remove_erase_if(rows, [&](const string & row) {
		vector<string> actRow;
		csvline_populate(actRow, row, DELIMITIER);
		return (actRow[BGIndex].empty() || actRow[IGIndex].empty());
	});

	//cout << rows.size() << endl;

	return transformToDataSet(rows, BGIndex, IGIndex);

}

bool Loader::loadFileToVector(vector<string> &rows) {
	ifstream in(filename);
	string line;
	if (in.fail()) {
		in.close();
		return false;
	}

	while (getline(in, line) && in.good()) {
		rows.push_back(line);
	}
	in.close();

	return true;
}

void Loader::csvline_populate(vector<string> &record, const string& line,
		char delimiter) {
	int linepos = 0;
	int inquotes = false;
	char c;
	//    int i;
	int linemax = line.length();
	string curstring;
	record.clear();

	while (line[linepos] != 0 && linepos < linemax) {

		c = line[linepos];

		if (!inquotes && curstring.length() == 0 && c == '"') {
			//beginquotechar
			inquotes = true;
		} else if (inquotes && c == '"') {
			//quotechar
			if ((linepos + 1 < linemax) && (line[linepos + 1] == '"')) {
				//encountered 2 double quotes in a row (resolves to 1 double quote)
				curstring.push_back(c);
				linepos++;
			} else {
				//endquotechar
				inquotes = false;
			}
		} else if (!inquotes && c == delimiter) {
			//end of field
			record.push_back(curstring);
			curstring = "";
		} else if (!inquotes && (c == '\r' || c == '\n')) {
			record.push_back(curstring);
			return;
		} else {
			curstring.push_back(c);
		}
		linepos++;
	}
	record.push_back(curstring);
	return;
}

double Loader::convertToDouble(string value) {
	stringstream aux;
	double result;
	aux.str(value);
	aux >> result;
	return result;
}

void Loader::findColumnsIndex(vector<string> header, int &BGIndex,
		int &IGIndex) {
	for (unsigned i = 0; i < header.size(); i++) {
		if (header[i] == BG) {
			BGIndex = i;
		} else if (header[i] == IG) {
			IGIndex = i;
		}
	}
}

